/**
 * \file lex.h
 * \brief A generic builder for lexers.
 **/

#ifndef R_LEX_H
#define R_LEX_H

#include "token.h"
#include "nfa.h"

struct RLexerT{
  /* Null-terminated input to the lexer. A string to be tokenized. */
  char* input;

  /* List of rules that are applied when matching the input. Use the
   * r_lex_* functions to add rules. */
  RVector rules;

  /* Number of environments */
  int environments;

  /* Stack of environments */
  RVector stack;

  /* NFAs (one for each environment) */
  NFANode** nfas;
};
typedef struct RLexerT RLexer;

struct RLexRuleT{
  /* id of the token returned. If 0, the token is simply consumed.*/
  int id;

  /* After matching the rule, to_env becomes the environment. */
  int to_env;
};
typedef struct RLexRuleT RLexRule;

/**
 * \brief Initialize a lexer.
 * \param[in] stacks The number of environments to allocate.
 **/
void r_lex_init(RLexer* lexer, int environments);

/**
 * \brief Add a rule to the lexer.
 **/
void r_lex_add(RLexer* lexer, char* pattern, int id, int env, int to_env);
/* TODO: There should be a way to specify that a given rule shouldn't copy
 * the text contents of the token because they are not needed (or are always
 * the same, think keywords or operators). */

/**
 * \brief Tokenize, and return a list of tokens.
 **/
RVector* r_lex_tokenize(RLexer* lexer);

#endif /* R_LEX_H */
